#include "registration.h"

#include <string.h>

#define MASK_CHAR 0x1F // 00011111

#define MASK0 0x3C // 00111100
#define MASK1 0xAA // 10101010
#define MASK2 0xAE // 10101110
#define MASK3 0xEB // 11101011
#define MASK4 0xAD // 10101101

bool CheckKey(const char* szName, const char* szKey)
{
	char szKeyTemp[KEY_LENGTH+1];
	
	if(szName && szKey)
	{
		if((strlen(szName) < MIN_NAME_LENGTH) || (strlen(szKey) != KEY_LENGTH))
		{
			return false;
		}
		if(GenerateKey(szName, szKeyTemp, KEY_LENGTH+1))
		{
			if(strcmp(szKey, szKeyTemp) == 0)
			{
				return true;
			}
		}
	}
	return false;
}

char GetKeyChar(int nKey)
{
	char result;

	result =  static_cast<char>((nKey + (nKey>>5)) & MASK_CHAR);

	if(result < 22)
	{
		result += 'A';
	}
	else
	{
		result += '0' - 22;
	}
	return result;
}

bool GenerateKey(const char* szName, char* szKey, int nLen)
{
	int key[KEY_LENGTH-1];
	int name[MIN_NAME_LENGTH];

	int sum;
	int nLenName;

	if(szName && szKey)
	{
		if((strlen(szName) < MIN_NAME_LENGTH) || (nLen < (KEY_LENGTH+1)))
		{
			return false;
		}

		nLenName = strlen(szName);

                      int i;
		for(i=0; i<MIN_NAME_LENGTH; i++)
		{
			name[i] = static_cast<int>(szName[i]);
		}

		for(i=0; i<KEY_LENGTH-1; i++)
		{
			key[i] = 0;
		}

		for(i=0; i<MIN_NAME_LENGTH-1; i++)
		{
			key[i] = ((name[i] + name[i+1])>>1) & MASK3;
		}

		sum = 0;
		for(;i<KEY_LENGTH-1; i++)
		{
			int cc = i % MIN_NAME_LENGTH;
			sum += ((name[i % MIN_NAME_LENGTH] & MASK0) | (nLenName & MASK2));
			sum &= MASK4;
			key[i] = (name[i % MIN_NAME_LENGTH] + sum) ^ MASK1;
		}

		// Generate Key String
		for(i=0; i<MIN_NAME_LENGTH-1; i++)
		{
			szKey[i] = GetKeyChar(key[i]);
		}

		szKey[i] = '-';
		for(; i<KEY_LENGTH-1; i++)
		{
			szKey[i+1] = GetKeyChar(key[i]);
		}
		szKey[KEY_LENGTH] = 0;
		return true;
	}
	return false;
}
